﻿using System.Collections.Generic;
using UnityEngine;

namespace GxFramework
{
    public class AssetBundleLoader
    {
        public AssetBundleManager _abMgr;
        public AssetBundleAssetLoader _asstLoader;
        int loaderMax = 10;

        List<AssetBundleInfo> _waitQueue = new List<AssetBundleInfo>();
        List<AssetBundleInfo> _loadingQueue = new List<AssetBundleInfo>();

        bool TryWait(AssetBundleInfo info)
        {
            if (info.status == AssetLoadStatus.Idle)
            {
                var deps = _abMgr.GetDirectDependencies(info.path);
                int len = null != deps ? deps.Length : 0;
                for (int i = 0; i < len; ++i)
                {
                    var depAb = _abMgr.GetAssetBundleInfo(deps[i], true);
                    TryWait(depAb);
                }

                if (info.status == AssetLoadStatus.Idle)
                {
                    _waitQueue.Add(info);
                    info.Wait();
                }
                return true;
            }
            return false;
        }
        public void Load(AssetBundleInfo info)
        {
            if ( TryWait(info))
            {
                HandleWaitQueue();
            }
        }
        void HandleWaitQueue()
        {
            //等待队列填充到加载队列
            while (_waitQueue.Count != 0
                && _loadingQueue.Count < loaderMax)
            {
                var toLoadInfo = _waitQueue[0];
                _waitQueue.RemoveAt(0);

                _loadingQueue.Add(toLoadInfo);

                toLoadInfo.Load();
            }
        }
        
        //检测加载中的完成状态
        public void Update()
        {
            int len = _loadingQueue.Count;

            //当前正在加载中（未完成）的个数
            int index=0;
            
            for (int i = 0; i < len; ++i)
            {
                var item = _loadingQueue[i];
                item.Update(this, _asstLoader);
                if (!item.isDone)
                {
                    if (index < i)
                        _loadingQueue[index] = item;
                    ++index;
                }
            }
            _loadingQueue.RemoveRange(index,len-index);

            HandleWaitQueue();
        }
        public bool IsDependencyDone(AssetBundleInfo info)
        {
            var deps = _abMgr.GetDirectDependencies(info.path);
            var len = null == deps ? 0 : deps.Length;
            for (int i = 0; i < len; ++i)
            {
                var depInfo = _abMgr.GetAssetBundleInfo(deps[i],true);
                if (!depInfo.isDone)
                    return false;
            }
            return true;
        }
    }
}